00001 /*! 00002 * \file 00003 * X-Forge Engine <br> 00004 * Copyright 2000-2002 Fathammer Ltd 00005 * 00006 * \brief Default implementation for a Bluetooth communication manager. 00007 * 00008 * $Id: XFuBluetoothMultiNetwork.cpp,v 1.2 2003/08/01 10:53:12 slehti Exp $ 00009 * $Date: 2003/08/01 10:53:12 $ 00010 * $Revision: 1.2 $ 00011 */ 00012 00013 #include <xforge.h> 00014 00015 #include <xfcore/net/XFcBtHandler.h> 00016 #include <xfcore/net/XFcBtClientWin.h> 00017 #include <xfcore/net/XFcObjectDataFrame.h> 00018 #include <xfcore/net/XFcCommunicationScheduler.h> 00019 #include <xfcore/net/XFcCommunicationConstants.h> 00020 #include <xfcore/net/socket/XFcSocketConstants.h> 00021 #include <xfcore/net/socket/XFcBtAddress.h> 00022 #include <xfcore/net/XFcUnknownSender.h> 00023 #include <xfcore/net/XFcClientLost.h> 00024 #include <xfcore/net/XFcDataReceiver.h> 00025 #include <xfcore/net/XFcObjectDataFrame.h> 00026 #include <xfcore/net/socket/XFcHostEntry.h> 00027 #include <xfcore/net/socket/XFcBtHostResolver.h> 00028 #include <xfcore/net/socket/XFcBtAdvertiser.h> 00029 #include <xfcore/net/XFcUdpEngine.h> 00030 #include <xfcore/net/socket/XFcBtCommService.h> 00031 #include <xfcore/net/socket/XFcBtServerSearch.h> 00032 00033 #include <xfutil/XFuSerializable.h> 00034 #include <xfutil/XFuNetwork.h> 00035 #include <xfutil/XFuNetworkEventHandler.h> 00036 #include <xfutil/XFuBluetoothMultiNetwork.h> 00037 00038 00039 XFuBluetoothMultiNetwork * XFuBluetoothMultiNetwork::create() 00040 { 00041 XFuBluetoothMultiNetwork * manager = new XFuBluetoothMultiNetwork; 00042 if (manager != NULL && !manager->init()) 00043 { 00044 delete manager; 00045 return NULL; 00046 } 00047 return manager; 00048 } 00049 00050 00051 XFuBluetoothMultiNetwork::XFuBluetoothMultiNetwork() 00052 { 00053 mNetworkEventHandlers = NULL; 00054 mCommunicationScheduler = NULL; 00055 mCommunicationHandler = NULL; 00056 mDefaultDataReceiver = NULL; 00057 mHostResolver = NULL; 00058 mCommunicationService = NULL; 00059 00060 mAcceptGameToken = 0; 00061 mCommunicationHandlerId = -1; 00062 mGamePort = 0; 00063 mSlaveClientId = -1; 00064 00065 mService = NULL; 00066 mBtServerSearch = NULL; 00067 } 00068 00069 00070 XFuBluetoothMultiNetwork::~XFuBluetoothMultiNetwork() 00071 { 00072 closeService(); 00073 deleteAllClients(); 00074 00075 removeAllEventHandlers(); 00076 00077 delete mService; 00078 delete mHostResolver; 00079 delete mNetworkEventHandlers; 00080 } 00081 00082 00083 INT XFuBluetoothMultiNetwork::init() 00084 { 00085 mCommunicationScheduler = (XFcCommunicationScheduler *)XFcCore::getCommunicationScheduler(); 00086 if (mNetworkEventHandlers == NULL) 00087 mNetworkEventHandlers = XFuDynamicArray<XFuNetworkEventHandler*>::create(5); 00088 00089 if (mCommunicationScheduler == NULL || 00090 mNetworkEventHandlers == NULL) return 0; 00091 00092 return 1; 00093 00094 } 00095 00096 00097 void XFuBluetoothMultiNetwork::runCommunicationScheduler() 00098 { 00099 mCommunicationScheduler->runScheduler(); 00100 } 00101 00102 00103 void XFuBluetoothMultiNetwork::reset() 00104 { 00105 XFCLOGFUNC("reset()", 3); 00106 closeService(); 00107 deleteAllClients(); 00108 removeAllEventHandlers(); 00109 00110 00111 mAcceptGameToken = 0; 00112 init(); 00113 00114 } 00115 00116 00117 INT XFuBluetoothMultiNetwork::initEnable(UINT16 aPort, INT aIsServer) 00118 { 00119 XFCLOGFUNC("initEnable()", 3); 00120 closeService(); 00121 deleteAllClients(); 00122 00123 00124 mService = XFcBtCommService::create(); 00125 00126 mGamePort = aPort; 00127 00128 // Are we bluetooth server, bt-slave. 00129 if (aIsServer) 00130 { 00131 if (aPort == 0 && mService) 00132 mGamePort = mService->getFirstFreeRFCOMMPort(); 00133 00134 } 00135 00136 if (mGamePort == 0xffff) 00137 mGamePort = 0; 00138 00139 mCommunicationHandler = XFcBtHandler::create(aIsServer); 00140 00141 return (mCommunicationHandler && mService) ? 1 : 0; 00142 00143 } 00144 00145 00146 INT XFuBluetoothMultiNetwork::enableClientService(UINT16 aPort) 00147 { 00148 XFCLOGFUNC("enableClientService()", 3); 00149 00150 XFcBtAddress *address = XFcBtAddress::create(); 00151 XFcBtClientWin *client = XFcBtClientWin::create(NULL); 00152 00153 if (address && client && initEnable(aPort, 1)) 00154 { 00155 address->setPort(mGamePort); 00156 00157 // Max client count must be more than 1 00158 INT32 maxClients = 2; 00159 00160 // Open server, will return 1 if success else 0 00161 if (mCommunicationHandler->openServer(*address, maxClients)) 00162 { 00163 mCommunicationHandler->setUnknownSenderHandler(this); 00164 mCommunicationHandler->setClientLost(this); 00165 00166 mCommunicationHandlerId = mCommunicationScheduler->addCommunicationHandler(mCommunicationHandler); 00167 mCommunicationHandler->listenConnection(*client); 00168 00169 INT32 clientId = mCommunicationScheduler->addClient(client); 00170 00171 if (clientId != XFCNET_CLIENTADD_ERROR) 00172 { 00173 00174 // XXXX 00175 mClients.put(clientId, client); 00176 delete address; 00177 address = NULL; 00178 mSlaveClientId = clientId; 00179 00180 return 1; 00181 } 00182 } 00183 } 00184 delete address; 00185 address = NULL; 00186 delete client; 00187 client = NULL; 00188 00189 return 0; 00190 } 00191 00192 00193 INT XFuBluetoothMultiNetwork::enableHostService() 00194 { 00195 XFCLOGFUNC("enableServerService()", 3); 00196 INT error = 0; 00197 00198 if (initEnable(0, 0)) 00199 { 00200 mCommunicationHandler->setUnknownSenderHandler(this); 00201 mCommunicationHandler->setClientLost(this); 00202 00203 mCommunicationHandlerId = mCommunicationScheduler->addCommunicationHandler(mCommunicationHandler); 00204 error = 1; 00205 } 00206 return error; 00207 } 00208 00209 00210 void XFuBluetoothMultiNetwork::closeService() 00211 { 00212 XFCLOGFUNC("closeService()", 3); 00213 stopDeviceDiscovery(); 00214 stopClientDiscovery(); 00215 stopAdvertiser(); 00216 00217 if (mCommunicationHandler != NULL) 00218 { 00219 mCommunicationHandler->closeService(); 00220 mCommunicationScheduler->removeCommunicationHandler(mCommunicationHandlerId); 00221 delete mCommunicationHandler; 00222 mCommunicationHandler = NULL; 00223 } 00224 delete mService; 00225 mService = NULL; 00226 } 00227 00228 00229 UINT32 XFuBluetoothMultiNetwork::getAcceptGameToken() 00230 { 00231 return mAcceptGameToken; 00232 } 00233 00234 00235 void XFuBluetoothMultiNetwork::setAcceptGameToken(UINT32 aAcceptGameToken) 00236 { 00237 mAcceptGameToken = aAcceptGameToken; 00238 } 00239 00240 00241 void XFuBluetoothMultiNetwork::sendGameConnectPacket(INT32 aClientId, UINT32 aGameToken) 00242 { 00243 XFcObjectDataFrame *frame = getPacketFrame(aClientId, XFCNET_NONGUARANTEED); 00244 if (frame) 00245 { 00246 frame->setReceiverId(0); 00247 void *buffer = frame->lock(); 00248 if (buffer) 00249 { 00250 memcpy(buffer, &aGameToken, 4); 00251 frame->setPacketSize(4); 00252 } 00253 frame->unlock(); 00254 } 00255 } 00256 00257 00258 00259 void XFuBluetoothMultiNetwork::deleteAllClients() 00260 { 00261 XFCLOGFUNC("deleteAllClients()", 3); 00262 if (!mCommunicationScheduler) 00263 return; 00264 00265 XFcHashtableIterator<UINT32, XFcBtClientWin *> itClient; 00266 00267 while (mClients.size() > 0) 00268 { 00269 itClient = mClients.begin(); 00270 INT32 key = itClient.getKey(); 00271 XFcClientCommWin *base_client = getClient(key); 00272 mCommunicationScheduler->removeClient(key); 00273 base_client->deinitializeClient(); 00274 mClients.remove(key); 00275 delete base_client; 00276 } 00277 mSlaveClientId = -1; 00278 } 00279 00280 00281 void XFuBluetoothMultiNetwork::removeAllClients() 00282 { 00283 XFCLOGFUNC("removeAllClients()", 3); 00284 if (!mCommunicationHandler) 00285 return; 00286 00287 XFcHashtableIterator<UINT32, XFcBtClientWin *> itClient; 00288 00289 while (mClients.size() > 0) 00290 { 00291 itClient = mClients.begin(); 00292 INT32 key = itClient.getKey(); 00293 removeClient(key); 00294 } 00295 00296 } 00297 00298 00299 XFcDataReceiver * XFuBluetoothMultiNetwork::getDefaultDataReceiver() 00300 { 00301 return mDefaultDataReceiver; 00302 } 00303 00304 00305 void XFuBluetoothMultiNetwork::setDefaultDataReceiver(XFcDataReceiver *aReceiver) 00306 { 00307 mDefaultDataReceiver = aReceiver; 00308 mCommunicationScheduler->setDataReceiver(aReceiver); 00309 } 00310 00311 00312 XFcDataReceiver * XFuBluetoothMultiNetwork::getDataReceiver(UINT32 aId) 00313 { 00314 return mCommunicationScheduler->getDataReceiver(aId); 00315 } 00316 00317 00318 INT XFuBluetoothMultiNetwork::addDataReceiver(UINT32 aId, XFcDataReceiver *aReceiver) 00319 { 00320 return mCommunicationScheduler->addDataReceiver(aId, aReceiver); 00321 } 00322 00323 00324 XFcDataReceiver * XFuBluetoothMultiNetwork::removeDataReceiver(UINT32 aId) 00325 { 00326 return mCommunicationScheduler->removeDataReceiver(aId); 00327 } 00328 00329 00330 void XFuBluetoothMultiNetwork::addEventHandler(XFuNetworkEventHandler *aHandler) 00331 { 00332 mNetworkEventHandlers->put(aHandler); 00333 } 00334 00335 00336 void XFuBluetoothMultiNetwork::removeEventHandler(XFuNetworkEventHandler *aHandler) 00337 { 00338 mNetworkEventHandlers->remove(aHandler); 00339 } 00340 00341 00342 void XFuBluetoothMultiNetwork::removeAllEventHandlers() 00343 { 00344 while (!mNetworkEventHandlers->isEmpty()) mNetworkEventHandlers->remove(); 00345 } 00346 00347 00348 XFcClientCommWin * XFuBluetoothMultiNetwork::getClient(INT32 aClientId) 00349 { 00350 XFCLOGFUNC("getClient()", 3); 00351 XFcHashtable<UINT32, XFcBtClientWin *>::iterator it; 00352 XFcClientCommWin * value = NULL; 00353 00354 it = mClients.find(aClientId); 00355 00356 if(it.isValid()) 00357 { 00358 value = it.getValue(); 00359 } 00360 00361 return value; 00362 } 00363 00364 00365 INT32 XFuBluetoothMultiNetwork::addClient(XFcAddress *aAddress, INT32 /*aTimeoutTime*/) 00366 { 00367 XFCLOGFUNC("addClient()", 3); 00368 XFcBtClientWin *client = NULL; 00369 INT32 clientId = -1; 00370 00371 if (!aAddress) 00372 return -1; 00373 00374 if ((client = XFcBtClientWin::create(aAddress)) == NULL) 00375 return -1; 00376 00377 switch (aAddress->getType()) 00378 { 00379 case XFCNET_AFBT: 00380 if (client->openClient() != -1) 00381 { 00382 clientId = mCommunicationScheduler->addClient(client); 00383 if (clientId != XFCNET_CLIENTADD_ERROR && clientId != XFCNET_ERROR) 00384 { 00385 // XXXX 00386 mClients.put(clientId, client); 00387 } 00388 } 00389 00390 break; 00391 default: 00392 XFcCore::systemPanic(XFCSTR("This address type is not supported")); 00393 break; 00394 } 00395 00396 if (clientId == -1) 00397 delete client; 00398 00399 return clientId; 00400 } 00401 00402 00403 void XFuBluetoothMultiNetwork::removeClient(INT32 aClientId) 00404 { 00405 XFCLOGFUNC("removeClient()", 3); 00406 INT32 cId = 0; 00407 00408 // If communication handler is not created we do not have anything to do. 00409 if (!mCommunicationHandler) 00410 return; 00411 00412 XFcBtClientWin * oldClient = (XFcBtClientWin *)getClient(aClientId); 00413 00414 if (oldClient) 00415 oldClient->deinitializeClient(); 00416 { 00417 // Remove client and deinitialize it 00418 mCommunicationScheduler->removeClient(aClientId); 00419 mClients.remove(aClientId); 00420 00421 // Listening client is created to backbuffer for incoming connections. 00422 // If client is removed we create new for new connection. 00423 // Service works as BT-Slave 00424 if (mCommunicationHandler->isServer()) 00425 { 00426 XFcBtClientWin *client = NULL; 00427 if ((client = XFcBtClientWin::create(NULL)) != NULL) 00428 { 00429 mCommunicationHandler->listenConnection(*client); 00430 cId = mCommunicationScheduler->addClient(client); 00431 00432 if (cId != XFCNET_CLIENTADD_ERROR && cId != XFCNET_ERROR) 00433 { 00434 // XXXX 00435 mClients.put(cId, client); 00436 mSlaveClientId = cId; 00437 } 00438 else 00439 XFcCore::systemPanic(XFCSTR("removeClient(), add client")); 00440 } 00441 else 00442 XFcCore::systemPanic(XFCSTR("removeClient(), new listener")); 00443 } 00444 } 00445 delete oldClient; 00446 } 00447 00448 00449 INT32 XFuBluetoothMultiNetwork::getRoundTripTime(INT32 aClientId) 00450 { 00451 return mCommunicationScheduler->getRoundTripTime(aClientId); 00452 } 00453 00454 00455 XFcObjectDataFrame * XFuBluetoothMultiNetwork::getPacketFrame(INT32 aClientId, XFCNET_MESSAGE_SLOT aSlot) 00456 { 00457 return mCommunicationScheduler->getPacketFrame(aClientId, aSlot); 00458 } 00459 00460 00461 XFcObjectDataFrame * XFuBluetoothMultiNetwork::getRecentStateFrame(INT32 aClientId, INT32 aRecentId) 00462 { 00463 return mCommunicationScheduler->getRecentStateFrame(aClientId, aRecentId); 00464 } 00465 00466 00467 void XFuBluetoothMultiNetwork::removeRecentStateFrame(INT32 aClientId, INT32 aRecentId) 00468 { 00469 mCommunicationScheduler->removeRecentStateFrame(aClientId, aRecentId); 00470 } 00471 00472 00473 INT32 XFuBluetoothMultiNetwork::send(INT32 aClientId, 00474 UINT32 aReceiverId, 00475 XFCNET_MESSAGE_SLOT aSlot, 00476 XFuSerializable *aSerializable) 00477 { 00478 XFcObjectDataFrame *frame = getPacketFrame(aClientId, aSlot); 00479 INT32 size = -1; 00480 if (frame) 00481 { 00482 00483 void *buffer = frame->lock(); 00484 if (buffer) 00485 { 00486 size = aSerializable->serialize((CHAR8*)buffer, frame->sizeofBuffer()); 00487 // If size is set to -1 XForge does not send the frame and frame is released. 00488 frame->setPacketSize(size); 00489 frame->setReceiverId(aReceiverId); 00490 00491 } 00492 frame->unlock(); 00493 } 00494 return size; 00495 } 00496 00497 00498 INT32 XFuBluetoothMultiNetwork::sendRecentState(INT32 aClientId, 00499 UINT32 aReceiverId, 00500 INT32 aRecentId, 00501 XFuSerializable *aSerializable) 00502 { 00503 XFcObjectDataFrame *frame = getRecentStateFrame(aClientId, aRecentId); 00504 INT32 size = -1; 00505 00506 if (frame) 00507 { 00508 void *buffer = frame->lock(); 00509 if (buffer) 00510 { 00511 size = aSerializable->serialize((CHAR8*)buffer, frame->sizeofBuffer()); 00512 frame->setPacketSize(size); 00513 frame->setReceiverId(aReceiverId); 00514 00515 } 00516 frame->unlock(); 00517 } 00518 return size; 00519 } 00520 00521 00522 void XFuBluetoothMultiNetwork::clientLost(INT32 aClientId) 00523 { 00524 XFCLOGFUNC("clientLost()", 3); 00525 removeClient(aClientId); 00526 00527 INT32 handlersNum = mNetworkEventHandlers->size(); 00528 INT32 i; 00529 00530 for (i = 0; i < handlersNum; i++) 00531 { 00532 mNetworkEventHandlers->get(i)->handleClientLost(aClientId); 00533 } 00534 } 00535 00536 00537 INT XFuBluetoothMultiNetwork::handleSender(const void *aAddress, const CHAR8 *aData, INT32 aLen) 00538 { 00539 XFCLOGFUNC("handleSender()", 3); 00540 00541 // Used magic number mAcceptGameToken here. 00542 // Make sure that gameToken is not addjusted with same value than mAcceptGameToken is. 00543 UINT32 gameToken = ~mAcceptGameToken; 00544 00545 if (((XFcAddress *)aAddress)->getType() == (INT32)XFCNET_AFBT && aLen == 4) 00546 { 00547 XFcBtClientWin * slaveClient = (XFcBtClientWin *)getClient(mSlaveClientId); 00548 // Get packet data 00549 memcpy(&gameToken, aData, 4); 00550 00551 // Test if packet data is game connect token packet 00552 if (gameToken == mAcceptGameToken) 00553 { 00554 if (slaveClient->isClientActive() == XFCNET_BT_LINESTATUS_ONHOLD) 00555 { 00556 // Accept client connection 00557 slaveClient->acceptConnection(1); 00558 00559 INT32 i; 00560 for (i = 0; i < (INT32)mNetworkEventHandlers->size(); i++) 00561 { 00562 // Notify event handler 00563 mNetworkEventHandlers->get(i)->handleClientAccepted(i); 00564 00565 } 00566 } 00567 } 00568 } 00569 if (((XFcAddress *)aAddress)->getType() != (INT32)XFCNET_AFBT || 00570 aLen != 4 || 00571 gameToken != mAcceptGameToken) 00572 { 00573 00574 XFcBtClientWin * slaveClient = (XFcBtClientWin *)getClient(mSlaveClientId); 00575 00576 if (slaveClient->isClientActive() == XFCNET_BT_LINESTATUS_ONHOLD) 00577 { 00578 // Disconnect client 00579 slaveClient->acceptConnection(0); 00580 00581 // Remove client, if we are bt-slave new listener is automatically created by remove client. 00582 removeClient(mSlaveClientId); 00583 00584 } 00585 } 00586 return 0; 00587 } 00588 00589 00590 INT XFuBluetoothMultiNetwork::startDeviceDiscovery() 00591 { 00592 XFCLOGFUNC("startDeviceDiscovery()", 3); 00593 // Stop device discovery 00594 stopDeviceDiscovery(); 00595 00596 // Delete host resolver 00597 if (!mHostResolver) 00598 mHostResolver = XFcBtHostResolver::create(); 00599 00600 // Do the device discovery, async found devices are returned througth deviceDiscovery callback. 00601 if (mHostResolver) 00602 return mHostResolver->inquiry(this); 00603 00604 return 0; 00605 } 00606 00607 00608 void XFuBluetoothMultiNetwork::stopDeviceDiscovery() 00609 { 00610 XFCLOGFUNC("stopDeviceDiscovery()", 3); 00611 if (mHostResolver) 00612 mHostResolver->cancelInquiry(); 00613 } 00614 00615 00616 INT XFuBluetoothMultiNetwork::startClientDiscovery(const XFcBtAddress *aAddress) 00617 { 00618 XFCLOGFUNC("startClientDiscovery()", 3); 00619 00620 INT retval = 0; 00621 00622 if (!mService) 00623 return 0; 00624 00625 if (aAddress) 00626 { 00627 // Have to fix this. 00628 XFcAdvertiser *advr = NULL; 00629 if ((advr = XFcBtAdvertiser::create(*aAddress, NULL, 0)) != NULL) 00630 retval = mService->inquiry(*advr, this); 00631 delete advr; 00632 return retval; 00633 } 00634 else 00635 { 00636 delete mBtServerSearch; 00637 if ((mBtServerSearch = XFcBtServerSearch::create()) != NULL) 00638 return mBtServerSearch->inquiry(this); 00639 } 00640 return retval; 00641 return 0; 00642 } 00643 00644 00645 void XFuBluetoothMultiNetwork::stopClientDiscovery() 00646 { 00647 // Not supported for 1.1 release 00648 XFCLOGFUNC("stopClientDiscovery()", 3); 00649 00650 if (mService) 00651 mService->cancelInquiry(); 00652 00653 if (mBtServerSearch) 00654 mBtServerSearch->cancelInquiry(); 00655 00656 delete mBtServerSearch; 00657 mBtServerSearch = NULL; 00658 } 00659 00660 00661 void XFuBluetoothMultiNetwork::deviceDiscovery(const XFcLinkedList<XFcHostEntry *> &aHostEntry) 00662 { 00663 XFcLinkedList<XFcHostEntry *>::forwardIterator it; 00664 INT32 handlersNum = mNetworkEventHandlers->size(); 00665 INT32 i; 00666 00667 if (aHostEntry.size() != 0) 00668 { 00669 for (it = aHostEntry.forwardBegin(); it != aHostEntry.forwardEnd(); it++) 00670 { 00671 for (i = 0; i < handlersNum; ++i) 00672 mNetworkEventHandlers->get(i)->handleDeviceDiscovered(it.getData()); 00673 } 00674 } 00675 } 00676 00677 00678 void XFuBluetoothMultiNetwork::deviceDiscovery(const XFcLinkedList<XFcAdvertiser *> &aAdvertiser) 00679 { 00680 XFcLinkedList<XFcAdvertiser *>::forwardIterator it; 00681 INT32 handlersNum = mNetworkEventHandlers->size(); 00682 INT32 i; 00683 00684 if (aAdvertiser.size() != 0) 00685 { 00686 for (it = aAdvertiser.forwardBegin(); it != aAdvertiser.forwardEnd(); it++) 00687 { 00688 for (i = 0; i < handlersNum; i++) 00689 mNetworkEventHandlers->get(i)->handleAdvertiseDiscovered(it.getData()); 00690 } 00691 } 00692 } 00693 00694 00695 INT XFuBluetoothMultiNetwork::startAdvertiser(const CHAR8 *aMessage) 00696 { 00697 XFCLOGFUNC("startAdveriser()", 3); 00698 00699 XFcBtAdvertiser *advertise = NULL; 00700 00701 if (!mService) 00702 return 0; 00703 00704 if ((advertise = XFcBtAdvertiser::create()) == NULL) 00705 return 0; 00706 00707 // Create default message if not given any 00708 if (aMessage == NULL) 00709 advertise->setMessageHeader("X-Forge server", 14); 00710 else 00711 advertise->setMessageHeader(aMessage, strlen(aMessage)); 00712 00713 // Set game port for advertiser 00714 advertise->setGamePort(mGamePort); 00715 00716 advertise->setAvailability(0xff); // Fully available. 00717 00718 INT error = mService->advertise(*advertise); 00719 00720 delete advertise; 00721 00722 return (error == XFCNET_ERROR) ? 0 : 1; 00723 00724 } 00725 00726 00727 void XFuBluetoothMultiNetwork::stopAdvertiser() 00728 { 00729 XFCLOGFUNC("stopAdvertiser()", 3); 00730 00731 if (!mService) 00732 return; 00733 00734 mService->cancelAdvertise(); 00735 }
![]() | ||||
![]() |
Confidential Copyright © 2002-2003 Fathammer | with doxygen by Dimitri van Heesch |